<script setup lang="ts">
//@ts-nocheck
import { ref } from "vue";
import DeviceCategoryApi from "@/api/DeviceCategoryApi";
import {
  addPoint,
  addPolyline,
  updatePoint,
  updatePolyline,
  uploadImg,
} from "@/api/pipe/index";
import { MAP_ACTION } from "@/views/pipe-network/constants";
import { useMapStore } from "@/store";
import { useLocalStore } from "@/views/pipe-network/store";
import _ from "lodash";
import { getAddressByLonLat } from "@/utils/map";

const IMG_BASE_URL = import.meta.env.VITE_APP_API_OSS;
const mapStore = useMapStore();
const { mapAction, splitLines } = storeToRefs(mapStore);
const localStore = useLocalStore();

const centerDialogVisible = ref(true);
const upload = ref();
const typeRef = ref("");
const typeOptions = ref([]);
const dynamicFields = ref([]);
const ruleFormRef = ref();
const imgManager = ref({});
const params = {
  pageSize: 1000,
  pageIndex: 1,
  pClassId: "01",
};
const emitEvents = defineEmits(["close"]);
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const isRepeatSubmit = ref(false);

const getDeviceCategoryList = () => {
  DeviceCategoryApi.api_query(params).then(({ data, errors, succeeded }) => {
    if (succeeded) {
      typeOptions.value = data.items.map((item: any) => {
        const { className, classId, classAttribute } = item;
        return {
          value: classId,
          label: className,
          fields: classAttribute,
        };
      });
      typeRef.value = data.items[0].className;
    }
  });
};
const onChange = (value: any) => {
  const { fields, label } = typeOptions.value.find(
    (item) => item.value === value
  );

  if (Array.isArray(dynamicFields.value)) {
    dynamicFields.value.forEach((item: any) => {
      delete rules[item.attr];
      delete form[item.attr];
    });
  }
  fields.forEach((item) => {
    /**
     * 图片类型的字段，值改成数组，方便扩展成支持6张图片
     */
    if (item.type === 4) {
      if (typeof item.value === "string") {
        item.value = item.value ? [{ url: IMG_BASE_URL + item.value }] : [];
      }
    }
  });
  dynamicFields.value = fields;
  fields.forEach((field: any) => {
    form[field.attr] = field.value;
  });
  form.classId = value;
  form.className = label;
};
const dealWithParams = (params, fields) => {
  fields.forEach((field: any) => {
    const { attr } = field;
    field.value = params[attr];
    delete params[attr];
  });
  params.pointAttribute = fields;
  return params;
};
const props = defineProps({
  position: Object, // 接收父组件传过来的点位坐标
  editor: Object,
});
const form = reactive(
  props.editor
    ? props.editor
    : {
        pointName: "",
        classId: "",
        className: "",
        position: JSON.stringify([
          props.position.lng.toFixed(8),
          props.position.lat.toFixed(8),
        ]),
        address: "",
        depth: 0,
        workStartDate: "",
        pointAttribute: "",
        remark: "",
        jsonPoint: JSON.stringify([
          props.position.lng.toFixed(8),
          props.position.lat.toFixed(8),
        ]),
        lon: props.position.lng.toFixed(8),
        lat: props.position.lat.toFixed(8),
      }
);
const rules = reactive({
  className: [{ required: true, message: "请选择管点类型" }],
  pointName: [
    {
      required: true,
      message: "请输入管点名称",
    },
  ],
  address: [
    {
      required: true,
      message: "请输入地址",
    },
  ],
});
const getLineParams = (params) => {
  const { jsonGeom } = params;
  const list = jsonGeom.split('coordinates":');
  const jsonLine = list[1].substring(0, list[1].length - 2);
  params.jsonLine = jsonLine;
  delete params.lineGisNo;
  delete params.jsonGeom;
  return params;
};
const saveSplitLines = async () => {
  const isPointDevideLineAction =
    mapAction.value === MAP_ACTION.DEVIDE_LINE_WITH_POINT;
  if (isPointDevideLineAction && splitLines.value.length > 0) {
    const res = await Promise.all([
      updatePolyline(splitLines.value[0]),
      addPolyline(getLineParams(splitLines.value[1])),
    ]); // .then((res) => {
    if (res[0].statusCode === 200 && res[1].statusCode === 200) {
      centerDialogVisible.value = false;
    } else {
      ElMessage.error("点打断的线，保存失败！");
    }
  }
};

const checkLength = (e, prop, maxLength) => {
  let b = 0; // 输入的字符数
  for (let i = 0, length = e.length; i < length; i++) {
    let c = e.charAt(i);
    if (/^[\u0000-\u00ff]$/.test(c)) {
      b++;
    } else {
      b += 2;
    }
    if (b > maxLength) {
      // 字符长度限制
      form[prop] = e.substr(0, i);
      if (/^[\u0000-\u00ff]$/.test(c)) {
        b--;
      } else {
        b -= 2;
      }
      break;
    }
  }
};

const changeUpload = async (_data, attr) => {
  const rst = beforeUpload(_data, attr);
  if (rst) {
    const list = imgManager.value[attr];
    if (!list) {
      imgManager.value[attr] = [_data.raw];
    } else {
      imgManager.value[attr].push(_data.raw);
    }
  }
};
const beforeUpload = (file, attr) => {
  const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
  const whiteList = ["jpg", "jpeg", "png", "bmp", "JPG", "JPEG", "BMP"];
  if (whiteList.indexOf(fileSuffix) === -1) {
    ElMessage.error("上传文件只能是jpg,jpeg,png,bmp,JPG,JPEG,BMP格式");
    form[attr].pop();
    return false;
  }
  const isLt2M = file.size / 1024 / 1024 < 5;
  if (!isLt2M) {
    ElMessage.error("上传文件大小不能超过 5MB");
    form[attr].pop();
    return false;
  }
  return true;
};

const handlePictureCardPreview = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

const updateRules = () => {
  const fields = dynamicFields.value;
  fields.forEach((field: any) => {
    rules[field.attr] = [
      {
        required: field.require,
        message: `请输入${field.attr}`,
      },
    ];
  });
};
const onClose = () => {
  if (mapStore.editingPipePoint) {
    mapStore.setEditingPipePoint(null);
  }
  emitEvents("close");
};
const onSubmit = async (formEl) => {
  if (!formEl) return;
  if (isRepeatSubmit.value) {
    ElMessage.warning("正在保存中...");
    return;
  }
  updateRules();
  const { editor } = props;
  let imgUpdateFailFlag = false;
  isRepeatSubmit.value = true;
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      ElMessage.warning("正在保存中...");
      const loop = async () => {
        for (let key in imgManager.value) {
          const list = form[key];
          const pathList = [];
          for (let i = 0; i < list.length; i++) {
            const { url } = list[i];
            if (url?.includes(IMG_BASE_URL)) {
              pathList.push(list[i]);
            } else {
              const { uid } = list[i];
              const file = imgManager.value[key].find(
                (item) => item.uid == uid
              );
              const rst = await uploadImg(file);
              if (rst.statusCode === 400) {
                ElMessage.error("图片上传失败！");
                imgUpdateFailFlag = true;
                return;
              }
              pathList.push({ url: IMG_BASE_URL + rst.data.path });
            }
          }
          form[key] = pathList;
        }
      };
      await loop();
      if (!imgUpdateFailFlag) {
        if (editor) {
          updatePoint(dealWithParams(form, dynamicFields.value)).then((res) => {
            if (res.statusCode === 200) {
              centerDialogVisible.value = false;
              ElMessage({
                message: "修改成功。",
                type: "success",
              });
              localStore.addUpdatePointAPICount();
            }
          });
        } else {
          const res = await addPoint(dealWithParams(form, dynamicFields.value));
          if (res.statusCode === 200) {
            saveSplitLines();
            centerDialogVisible.value = false;
            ElMessage({
              message: "已保存成功。",
              type: "success",
            });
            localStore.addUpdatePointAPICount();
          }
        }
        emitEvents("close");
      }
      isRepeatSubmit.value = false;
    } else {
      isRepeatSubmit.value = false;
    }
  });
};
const onSubmitDebounce = _.debounce(onSubmit, 2000, {
  leading: false,
  trailing: true,
});
watchEffect(() => {
  const { editor } = props;
  if (editor) {
    let { pointAttribute = [], latlng } = editor;
    const [lat, lon] = latlng;
    const someDynamicFields = {};
    if (typeof pointAttribute === "string") {
      pointAttribute = JSON.parse(pointAttribute);
    }
    if (Array.isArray(pointAttribute)) {
      pointAttribute.forEach((item) => {
        someDynamicFields[item.attr] = item.value;
      });
    } else if (typeof pointAttribute === "object") {
      Object.keys(pointAttribute).forEach((key) => {
        someDynamicFields[key] = pointAttribute[key];
      });
    }
    dynamicFields.value = pointAttribute;
    const obj = {
      lon,
      lat,
      ...someDynamicFields,
    };
    Object.keys(obj).forEach((key) => {
      form[key] = obj[key];
    });
    try {
      const { coordinates } = JSON.parse(form.jsonGeom);
      form.jsonPoint = JSON.stringify(coordinates);
    } catch (e) {}
    centerDialogVisible.value = true;
  }
});
watchEffect(() => {
  if (
    (props.position || props.editor) &&
    (!form.address || form.address.length === 0)
  ) {
    const { lat, lng, lon } = props.position || props.editor;
    getAddressByLonLat(lng || lon, lat).then((res) => {
      if (res.status === "1") {
        const {
          regeocode: { formatted_address },
        } = res;
        form.address = formatted_address;
      }
    });
  }
});
onMounted(() => {
  if (!props.editor) {
    getDeviceCategoryList();
  }
});
</script>

<template>
  <el-dialog
    v-model="centerDialogVisible"
    :title="editor ? '修改管点信息' : '添加管点信息'"
    width="1000"
    align-center
    @close="onClose"
    :close-on-press-escape="false"
    :close-on-click-modal="false"
  >
    <el-form
      ref="ruleFormRef"
      :model="form"
      class="content"
      label-position="right"
      label-width="auto"
    >
      <el-form-item label="经度">
        <el-input v-model="form.lon" disabled type="number" />
      </el-form-item>
      <el-form-item label="纬度">
        <el-input v-model="form.lat" disabled type="number" />
      </el-form-item>
      <el-form-item label="管点类型" prop="className" :rules="rules.className">
        <el-select
          v-model="form.className"
          placeholder="请选择管点类型"
          @change="onChange"
          :disabled="!!editor"
        >
          <el-option
            v-for="item in typeOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="管点名称" prop="pointName" :rules="rules.pointName">
        <el-input
          placeholder="请输入管点名称"
          v-model="form.pointName"
          maxlength="20"
          @input="(e) => checkLength(e, 'pointName', 50)"
        />
      </el-form-item>
      <el-form-item label="地址" prop="address" :rules="rules.address">
        <el-input
          v-model="form.address"
          maxlength="100"
          @input="(e) => checkLength(e, 'address', 100)"
        />
      </el-form-item>
      <el-form-item
        v-for="option in dynamicFields"
        :key="option.attr"
        :label="option.attr"
        :prop="option.attr"
        :rules="{
          required: option.require,
          message: `请输入${option.attr}`,
        }"
      >
        <el-input
          v-if="option.type === 1"
          v-model="form[option.attr]"
          type="number"
          pattern="[0-9]*"
        />
        <el-input v-if="option.type === 2" v-model="form[option.attr]" />
        <el-select
          v-if="option.type === 3"
          v-model="form[option.attr]"
          @change="(value) => (form[option.attr] = value)"
        >
          <el-option
            v-for="item in option.options"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>
        <template v-if="option.type === 4">
          <el-upload
            ref="upload"
            action="#"
            list-type="picture-card"
            :auto-upload="false"
            :limit="9"
            accept=".jpg,.jpeg,.png,.bmp,.JPG,.JPEG,.BMP"
            v-model:file-list="form[option.attr]"
            :on-change="(file) => changeUpload(file, option.attr)"
            class="no-wrap"
            :on-preview="handlePictureCardPreview"
          >
            <el-icon><Plus /></el-icon>
          </el-upload>
          <el-dialog v-model="dialogVisible">
            <img w-full :src="dialogImageUrl" alt="Preview Image" />
          </el-dialog>
        </template>
      </el-form-item>
      <el-form-item label="投运时间" prop="workStartDate">
        <el-date-picker
          v-model="form.workStartDate"
          type="date"
          placeholder="请选择投运时间"
          :size="middle"
          style="width: 100%"
        />
      </el-form-item>
      <el-form-item label="埋深" prop="depth">
        <el-input v-model="form.depth" type="number" :min="0" />
        <span style="position: absolute; right: -20px">米</span>
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="form.remark" placeholder="备注说明" />
      </el-form-item>
      <el-form-item class="twoButtons">
        <el-button
          type="primary"
          @click="onSubmitDebounce(ruleFormRef)"
          :disabled="isRepeatSubmit"
          >保存</el-button
        >
        <el-button
          :disabled="isRepeatSubmit"
          @click="
            centerDialogVisible = false;
            emitEvents('close');
          "
          >取消</el-button
        >
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<style scoped lang="scss">
.content {
  padding: 10px 50px 0 30px;
}

.row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;

  span:nth-child(1) {
    width: 100px;
    padding-right: 12px;
    text-align: right;
  }
}

.no-wrap {
  :deep(li) {
    width: 80px;
    height: 80px;
  }

  :deep(.el-upload) {
    width: 80px;
    height: 80px;
  }
}

.the-img {
  position: relative;
  left: 0;
  transform: scale(0.5);
}

.twoButtons {
  :deep(.el-form-item__content) {
    display: flex;
    justify-content: space-around;
    margin-bottom: 30px;
    margin-left: 50px;
  }
}
</style>
